﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using UL360Data;
using UL360SurveyCommon;
using System.Threading;
using System.Globalization;

namespace UL360SurveyWeb
{
    public partial class Default : System.Web.UI.Page
    {
        string MethodName = System.Reflection.MethodBase.GetCurrentMethod().Name;
        private int ParticipantId {get; set;}
        private Sprak Language { get; set; }

        #region Override language
        protected override void InitializeCulture()
        {
            string text = Request.QueryString["FormType"];

            //Set participant to Participant's ID
            int participantId = -1;
            
            //Get requested survey answerer from querystring
            if (Request.QueryString["sa"] != null)
            {
                int.TryParse(URLEncrypt.Decrypt(Request.QueryString["sa"]), out participantId);
            }
            else if ((Request.QueryString["sa"] != null && participantId <= 0) || (Request.QueryString["sa"] == null && participantId <= 0))
            {
                //Page redirect for non authorized visitors
                Response.Redirect(Page.ResolveUrl("~/NotAuthorized.aspx"));
                Response.Clear();
                Response.End();
            }
            
            //Set participant ID that holds the ID all through the thread
            ParticipantId = participantId;

            //Get participant's language
            using (var db = new UL360Entities())
            {
                Language = db.Deltagares.Include("Sprak").Where(p => p.deltagarid == ParticipantId).DefaultIfEmpty(null).First().Sprak;
            }

            //Get language to set titles and text to right language in the survey
            string culture = System.Configuration.ConfigurationManager.AppSettings[Language.sprakid.ToString()];

            if (!String.IsNullOrEmpty(culture) && culture != "sv-SE")
            {
                UICulture = culture;
                Culture = culture;

                Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
                Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
            }

            base.InitializeCulture(); 
        }
        #endregion

        #region Page Load
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                #region Getting ID:s to be able to present the right survey when the page is loading
                    //Set default surveyType
                    SurveyType surveyType = UL360Data.SurveyType.OriginalCourse;

                    //Get requested surveyType from querystring
                    if (Request.QueryString["FormType"] != null)
                    {
                        int formType = 0;
                        int.TryParse(Request.QueryString["FormType"], out formType);
                        surveyType = (SurveyType)formType;
                    }
               #endregion

                //Set hidden field ParticipantID to particpant's id
                ParticipantID.Value = ParticipantId.ToString();

                //Set FormType
                SurveyType.Value = ((int)surveyType).ToString();

                if (((int)surveyType).ToString() == "0")
                {
                    CoursePart1.Visible = true;
                    CoursePart2.Visible = false;
                }
                else if (((int)surveyType).ToString() == "1")
                {
                    CoursePart1.Visible = false;
                    CoursePart2.Visible = true;
                }

                //Course variable holding participant's course
                Kurstillfalle course;
                //Variable holding course tutors name
                List<Handledare> tutors;
                //Variable holding form id
                int formid;
                SurveyForm form;
                
                //End date for the course
                DateTime enddate;
                //Extended course date for the course
                DateTime extendeddate;
                //Todays date
                DateTime today = DateTime.Now;
                //Intervals
                SurveyIntervalSetting intervals;
                int totaldays;

                //Mails sent for course
                List<SurveyMailedStatus> surveyMails = new List<SurveyMailedStatus>();

                //Boolean variable that is used to check if the participant already answered or not
                bool alreadyAnswered = false;

                //Get participant's language and course from db and get the tutors for the course
                using (var db = new UL360Entities())
                {

                    //Get participant's course
                    course = db.Deltagares.Include("Kurstillfalle").Where(p => p.deltagarid == ParticipantId).DefaultIfEmpty(null).First().Kurstillfalle;

                    //Get form id
                    form = db.SurveyForms.Include("SurveyQuestions.SurveyQuestionTexts.Sprak").Where(f => f.SurveyType == surveyType && f.DateCreated <= course.slutdatum).OrderByDescending(f => f.DateCreated).First();

                    formid = form.SurveyFormId;

                    //Get tutor for the course
                    tutors = db.Kurstillfalles.Include("Handledare").Include("Handledares").Where(c => c.kursid == course.kursid).DefaultIfEmpty(null).First().Handledares.ToList();
                    tutors.Add(db.Kurstillfalles.Include("Handledare").Include("Handledares").Where(c => c.kursid == course.kursid).DefaultIfEmpty(null).First().Handledare);

                    //Get end date for the course
                    enddate = course.slutdatum;

                    //Get extended course date for the course
                    extendeddate = (DateTime)course.DatumFordjupningsdag;

                    //Get & set intervals
                    intervals = db.SurveyIntervalSettings.First();
                    totaldays = (intervals.SendSurveyMailInterval * 7) + (intervals.SendReminderMailInterval * 7) + (intervals.LastAnswerInterval * 7);
                    
                    //Get surveymails
                    surveyMails = db.SurveyMailedStatus.Where(m => m.fk_KursId == course.kursid).ToList();
                    
                    //Check if participant already answered this survey and set variable alreadyAnswered to true if this is the case
                    if ((db.SurveyForms.Where(f => f.SurveyFormId == formid).First().SurveyAnswerScales.Where(p => p.fk_DeltagarId == ParticipantId).Count() > 0) ||
                       (db.SurveyForms.Where(f => f.SurveyFormId == formid).First().SurveyAnswerTexts.Where(p => p.fk_DeltagarId == ParticipantId).Count() > 0))
                    {
                        alreadyAnswered = true;
                    }
                }

                //Set default last answer date for the original course survey
                DateTime lastAnswerDate = enddate.AddDays(totaldays);

                //Set default last answer date for the extended course survey
                DateTime lastAnswerExtDate = extendeddate.AddDays(totaldays);

                if (surveyType == UL360Data.SurveyType.OriginalCourse)
                {
                    //Set last answerdate from mails sent, i.e. if mail was delayed, set last answer date with regard for this
                    if (surveyMails.Where(m => m.MailType == MailType.ReminderMail).DefaultIfEmpty(null).First() != null)
                    {
                        //If reminder mail was sent, set lastanswerdate to LastAnswerInterval from remindermail
                        lastAnswerDate = surveyMails.Where(m => m.MailType == MailType.ReminderMail).First()
                            .DateSent.AddDays(intervals.LastAnswerInterval * 7);
                    }
                    else if (surveyMails.Where(m => m.MailType == MailType.SurveyMail).DefaultIfEmpty(null).First() != null)
                    {
                        //If surveyMail was sent, set lastanswerdate to SendReminderInterval + LastAnswerInterval from SendSurveyMailInterval
                        lastAnswerDate = surveyMails.Where(m => m.MailType == MailType.SurveyMail).First()
                            .DateSent.AddDays((intervals.SendReminderMailInterval * 7) + (intervals.LastAnswerInterval * 7));
                    }
                }
                else if (surveyType == UL360Data.SurveyType.ExtendedCourse && extendeddate != null)
                {
                    //Set last answerdate from mails sent, i.e. if mail was delayed, set last answer date with regard for this
                    if (surveyMails.Where(m => m.MailType == MailType.ExtReminderMail).DefaultIfEmpty(null).First() != null)
                    {
                        //If reminder mail was sent, set lastanswerdate to LastAnswerInterval from remindermail
                        lastAnswerExtDate = surveyMails.Where(m => m.MailType == MailType.ExtReminderMail).First()
                            .DateSent.AddDays(intervals.LastAnswerInterval * 7);
                    }
                    else if (surveyMails.Where(m => m.MailType == MailType.ExtSurveyMail).DefaultIfEmpty(null).First() != null)
                    {
                        //If surveyMail was sent, set lastanswerdate to SendReminderInterval + LastAnswerInterval from SendSurveyMailInterval
                        lastAnswerExtDate = surveyMails.Where(m => m.MailType == MailType.ExtSurveyMail).First()
                            .DateSent.AddDays((intervals.SendReminderMailInterval * 7) + (intervals.LastAnswerInterval * 7));
                    }
                }

                #region Redirection if the last date to answer this survey has passed
                //Compare dates to see if last answer date has passed and if so, redirecting to another page
                if (surveyType == UL360Data.SurveyType.OriginalCourse)
                {
                    int ispassed = DateTime.Compare(today, lastAnswerDate);
                    if (ispassed > 0)
                    {
                        Response.Redirect(Page.ResolveUrl("~/TooLate.aspx?langid=" + Language.sprakid.ToString()));
                        Response.Clear();
                        Response.End();
                    }
                }
                else if (surveyType == UL360Data.SurveyType.ExtendedCourse)
                {
                    int extispassed = DateTime.Compare(today, lastAnswerExtDate);
                    if (extispassed > 0)
                    {
                        Response.Redirect(Page.ResolveUrl("~/TooLate.aspx?langid=" + Language.sprakid.ToString()));
                        Response.Clear();
                        Response.End();
                    }
                }
                #endregion

                #region Redirection if participant already answered this survey
                //Redirect if the participant already answered this particular survey
                    if (alreadyAnswered == true)
                    {
                        Response.Redirect(Page.ResolveUrl("~/AlreadyAnswered.aspx?langid=" + Language.sprakid.ToString()));
                        Response.Clear();
                        Response.End();
                    }
                #endregion

                #region Setting texts in the survey to let the participant know which course the survey is about

                    //Set form id
                    FormID.Value = formid.ToString();

                    //Set course dates and tutor names
                    CourseDate.Text = course.startdatum.ToString("yyyy-MM-dd") + " -- " + course.slutdatum.ToString("yyyy-MM-dd");

                    //Set course name
                    CourseName.Text = course.organisation;

                    //Set course id
                    CourseID.Value = course.kursid.ToString();

                    //Get tutors for the course
                    if (TutorName.Text == "")
                    {
                        foreach (Handledare tutor in tutors)
                        {
                            TutorName.Text += tutor.fornamn + " " + tutor.efternamn + ", ";
                        }

                        if (!string.IsNullOrEmpty(TutorName.Text))
                        {
                            TutorName.Text = TutorName.Text.Substring(0, TutorName.Text.Length - 2);
                        }
                    }

                #endregion

                #region Bind survey questions for this course and language to be presented for the participant

                    if (course != null) {
                        //Setting and binding datasource
                        if (form != null)
                        {
                            if (form.SurveyQuestions.Where(q => q.QuestionType == QuestionType.Scale).ToList().Count > 0)
                            {
                                ScaleSurveyQuestions.DataSource = form.SurveyQuestions.Where(q => q.QuestionType == QuestionType.Scale).ToList().SelectMany(qt => qt.SurveyQuestionTexts.Where(l => l.fk_SprakId == Language.sprakid)).ToList();
                                ScaleSurveyQuestions.DataBind();
                            }
                            else 
                            {
                                ScaleQuestionsContainer.Style.Add("display", "none");
                            }

                            if (form.SurveyQuestions.Where(q => q.QuestionType == QuestionType.Text).ToList().Count > 0)
                            {
                                TextSurveyQuestions.DataSource = form.SurveyQuestions.Where(q => q.QuestionType == QuestionType.Text).ToList().SelectMany(qt => qt.SurveyQuestionTexts.Where(l => l.fk_SprakId == Language.sprakid)).ToList();
                                TextSurveyQuestions.DataBind();
                            }
                            else
                            {
                                TextQuestionsContainer.Style.Add("display", "none");
                            }
                        }
                    }

                #endregion

            }
            catch (Exception exc)
            {
                if (!exc.GetType().IsAssignableFrom(typeof(System.Threading.ThreadAbortException)))
                {
                    string errorTicket = UL360SurveyCommon.LoggerCommon.LogNewEntry(new UL360SurveyCommon.LoggerCommon.LogNewEntryDelegate(UL360SurveyWeb.Utils.Logger.LogNewEntry), MethodName, exc.ToString(), (int)SurveyLoggingLevel.Error);
                }
            }
        }
        #endregion

        #region Send_Click
        protected void Send_Click(object sender, EventArgs e)
        {

            //Get ID:S - Code to get data from web form to code behind to be able to save answers in database
            //Get participant ID
            int id = Convert.ToInt16(ParticipantID.Value);
            
            //Get course ID
            int course = Convert.ToInt16(CourseID.Value);
            
            //Get survey form ID
            int stype = Convert.ToInt16(SurveyType.Value);
            int formid = Convert.ToInt16(FormID.Value);

            //Boolean variable that is used to check if the prticipant already answered or not
            bool alreadyAnswered = false;

            #region Get answers from aspx - Code to get all available answers from survey
            //Get string with all answers and question id:s
            string scaleAnswerValues = ScaleAnswers.Value;

            //Make array and fill with splitted string from scaleAnswerValues
            string[] values;
            values = scaleAnswerValues.Split(',');

            //Get string with all answers and question id:s from hidden fields in aspx
            string textAnswers = TextAnswers.Value;
            string textAnswerIds = TextIDs.Value;

            ArrayList textids = new ArrayList();
            ArrayList texts = new ArrayList();

            //Make array and fill with id:s for the text answer texts
            if (!String.IsNullOrEmpty(textAnswerIds.Trim()))
            {
                textids.AddRange(textAnswerIds.Split(',').ToList());

                //Remove the substring "#####" from beginning of first text answer string
                if (textAnswers != "")
                {
                    textAnswers = textAnswers.Remove(0, 5);
                    texts.AddRange(textAnswers.Split(new string[] { ",#####" }, StringSplitOptions.RemoveEmptyEntries).Select(text => text.Trim()).Where(s => !string.IsNullOrEmpty(s)).ToList());
                }
            }
            
            #endregion

            using (UL360Entities db = new UL360Entities())
            {
                //Check if participant already has answered
                if ((db.SurveyForms.Where(f => f.SurveyFormId == formid).First().SurveyAnswerScales.Where(p => p.fk_DeltagarId == id).Count() <= 0) ||
                       (db.SurveyForms.Where(f => f.SurveyFormId == formid).First().SurveyAnswerTexts.Where(p => p.fk_DeltagarId == id).Count() <= 0))
                {
                    #region Loop through scale answers
                    
                        int i = 0;

                        //Loop through each scale question item in control to get answers
                        foreach (RepeaterItem scaleQuestionItem in ScaleSurveyQuestions.Items)
                        {
                            //Get question ID
                            int scaleQuestionTextId = Convert.ToInt16(((HiddenField)scaleQuestionItem.FindControl("ScaleQuestionTextId")).Value);
                            int quid = db.SurveyQuestionTexts.Where(t => t.SurveyQuestionTextId == scaleQuestionTextId).First().fk_SurveyQuestionId;
                            //Get answer value
                            int answer = Convert.ToInt16(values.GetValue(i));

                            SurveyAnswerScale scale = new SurveyAnswerScale
                            {
                                fk_SurveyQuestionId = quid,
                                fk_DeltagarId = id,
                                fk_KursId = course,
                                fk_SurveyFormId = formid,
                                ScaleAnswer = answer,
                            };

                            i++;
                            //Insert new scale answers object
                            db.SurveyAnswerScales.Add(scale);
                        }
                    #endregion

                    #region Loop through text answers
                        int j = 0;

                        //Question text id holder
                        string textQuestionTextId;

                        foreach (string txtid in textids)
                        {
                            //Get Question ID
                            textQuestionTextId = txtid.ToString();
                            int qtid = Convert.ToInt16(textQuestionTextId);
                            int quid = db.SurveyQuestionTexts.Where(t => t.SurveyQuestionTextId == qtid).First().fk_SurveyQuestionId;
                            //Get answer text

                            string textanswer = texts[j].ToString();

                            SurveyAnswerText text = new SurveyAnswerText
                            {
                                fk_SurveyQuestionId = quid,
                                fk_DeltagarId = id,
                                fk_KursId = course,
                                fk_SurveyFormId = formid,
                                TextAnswer = textanswer,
                            };

                            j++;
                            //Insert new text answers object
                            db.SurveyAnswerTexts.Add(text);
                        }
                    #endregion

                    #region Submit answers to database

                        try
                        {
                            //Sumbit answers to the database
                            db.SaveChanges();

                            //Redirect after answers have been sent
                            Response.Redirect(Page.ResolveUrl("~/SurveySent.aspx?langid=" + Language.sprakid.ToString()));
                        }
                        catch (Exception exc)
                        {
                            //Looging the exception in database if there are any errors trying to save
                            string errorTicket = UL360SurveyCommon.LoggerCommon.LogNewEntry(new UL360SurveyCommon.LoggerCommon.LogNewEntryDelegate(UL360SurveyWeb.Utils.Logger.LogNewEntry), MethodName, exc.ToString(), (int)SurveyLoggingLevel.Error);
                        }

                    #endregion
                }

                else
                {
                    alreadyAnswered = true;
                }
            }

            //Redirect to another page if this participant already answered this survey
            if (alreadyAnswered == true)
            {
                Response.Redirect(Page.ResolveUrl("~/AlreadyAnswered.aspx?langid=" + Language.sprakid.ToString()));
                Response.Clear();
                Response.End();
            }

        }
        #endregion
    }
}